use log::error;

///
/// # Arguments
/// * `content` - 文件内容
/// * `keyword` - 搜索关键字，支持条件语法：[NOT] (关键字 [AND|OR 关键字...])
///
/// # Returns
/// 返回`Option<String>`，匹配时返回包含匹配内容的字符串，否则返回None
pub fn get_matched(content: &str, keyword: &str) -> Option<String> {
    match parse_condition(keyword) {
        Ok(condition) => {
            let evaluation_result = evaluate_condition(content, &condition);

            if evaluation_result {
                // 调整处理逻辑：简单条件返回匹配行的上下文，复杂条件返回所有匹配行
                match &condition {
                    Condition::Simple(keyword) => {
                        let context = find_matching_context(content, keyword);

                        if let Some(context) = context {
                            Some(context)
                        } else {
                            Some(content.lines().take(3).collect::<Vec<_>>().join("\n"))
                        }
                    }
                    _ => {
                        let matched_lines = find_all_matching_lines(content, &condition);
                        Some(matched_lines.join("\n"))
                    }
                }
            } else {
                None
            }
        }
        Err(e) => {
            error!("解析条件语法失败: {}, 输入: '{}'", e, keyword);
            None
        }
    }
}

/// 查找所有匹配条件的行
fn find_all_matching_lines(content: &str, condition: &Condition) -> Vec<String> {
    let mut matched_lines = Vec::new();

    // 对于简单条件，直接查找包含关键字的行
    if let Condition::Simple(keyword) = condition {
        for line in content.lines() {
            if line.contains(keyword) {
                matched_lines.push(line.to_string());
            }
        }
        return matched_lines;
    }

    // 对于复杂条件，我们需要更智能的处理
    // 首先评估整个内容是否满足条件
    if !evaluate_condition(content, condition) {
        return Vec::new();
    }

    // 对于复杂条件，我们返回所有包含至少一个关键字的行
    let keywords = extract_keywords(condition);
    for line in content.lines() {
        if keywords.iter().any(|keyword| line.contains(keyword)) {
            matched_lines.push(line.to_string());
        }
    }

    matched_lines
}

/// 从条件中提取所有关键字
fn extract_keywords(condition: &Condition) -> Vec<&str> {
    let mut keywords = Vec::new();
    extract_keywords_recursive(condition, &mut keywords);
    keywords
}

/// 递归提取关键字
fn extract_keywords_recursive<'a>(condition: &'a Condition, keywords: &mut Vec<&'a str>) {
    match condition {
        Condition::Simple(keyword) => {
            keywords.push(keyword);
        }
        Condition::Not(inner) => {
            extract_keywords_recursive(inner, keywords);
        }
        Condition::And(conditions) | Condition::Or(conditions) => {
            for cond in conditions {
                extract_keywords_recursive(cond, keywords);
            }
        }
    }
}

/// 查找简单条件的匹配上下文（前一行 + 匹配行 + 后一行）
fn find_matching_context(content: &str, keyword: &str) -> Option<String> {
    let lines: Vec<&str> = content.lines().collect();

    for (i, line) in lines.iter().enumerate() {
        if line.contains(keyword) {
            let mut context_lines = Vec::new();

            // 添加前一行（如果存在）
            if i > 0 {
                context_lines.push(lines[i - 1]);
            }

            // 添加当前匹配行
            context_lines.push(line);

            // 添加后一行（如果存在）
            if i < lines.len() - 1 {
                context_lines.push(lines[i + 1]);
            }

            return Some(context_lines.join("\n"));
        }
    }

    None
}

/// 条件类型枚举
#[derive(Debug, PartialEq)]
enum Condition {
    Simple(String),
    Not(Box<Condition>),
    And(Vec<Condition>),
    Or(Vec<Condition>),
}

/// 解析条件语法
fn parse_condition(input: &str) -> Result<Condition, String> {
    let input = input.trim();

    if input.is_empty() {
        return Err("空条件".to_string());
    }

    // 处理 NOT 条件
    if let Some(stripped) = input.strip_prefix("NOT ") {
        let inner = parse_condition(stripped)?;
        let result = Condition::Not(Box::new(inner));
        return Ok(result);
    }

    // 处理括号表达式 - 修复逻辑：需要找到匹配的最外层括号
    if input.starts_with('(') {
        let mut balance = 0;
        let mut end_index = None;

        for (i, c) in input.chars().enumerate() {
            match c {
                '(' => balance += 1,
                ')' => {
                    balance -= 1;
                    if balance == 0 {
                        end_index = Some(i);
                        break;
                    }
                }
                _ => {}
            }
        }

        if let Some(end_index) = end_index {
            // 检查括号后是否还有内容
            if end_index == input.len() - 1 {
                // 整个表达式在括号内
                let inner = &input[1..end_index];
                let result = parse_logical_expression(inner)?;
                return Ok(result);
            } else {
                // 括号后还有内容，需要解析逻辑表达式
                let inner = &input[1..end_index];
                let inner_condition = parse_logical_expression(inner)?;
                let remaining = &input[end_index + 1..].trim();

                if !remaining.is_empty() {
                    // 处理括号后的逻辑运算符
                    if let Some(remaining_stripped) = remaining.strip_prefix("AND ") {
                        let other = parse_condition(remaining_stripped)?;
                        let result = Condition::And(vec![inner_condition, other]);
                        return Ok(result);
                    } else if let Some(remaining_stripped) = remaining.strip_prefix("OR ") {
                        let other = parse_condition(remaining_stripped)?;
                        let result = Condition::Or(vec![inner_condition, other]);
                        return Ok(result);
                    }
                }
            }
        }
    }

    // 没有括号或括号处理失败，尝试解析逻辑表达式
    parse_logical_expression(input)
}

/// 解析逻辑表达式 (AND/OR)
fn parse_logical_expression(input: &str) -> Result<Condition, String> {
    let input = input.trim();

    // 按优先级处理：先处理 OR，再处理 AND
    // 检查 OR 连接（优先级较低）
    let or_parts: Vec<&str> = input.split(" OR ").collect();
    if or_parts.len() > 1 {
        let conditions: Result<Vec<Condition>, String> =
            or_parts.iter().map(|part| parse_condition(part)).collect();
        let result = Condition::Or(conditions?);
        return Ok(result);
    }

    // 检查 AND 连接（优先级较高）
    let and_parts: Vec<&str> = input.split(" AND ").collect();
    if and_parts.len() > 1 {
        let conditions: Result<Vec<Condition>, String> =
            and_parts.iter().map(|part| parse_condition(part)).collect();
        let result = Condition::And(conditions?);
        return Ok(result);
    }

    // 没有逻辑连接符，当作简单条件处理
    let result = Condition::Simple(input.to_string());
    Ok(result)
}

/// 评估条件是否在内容中满足
fn evaluate_condition(content: &str, condition: &Condition) -> bool {
    let result = match condition {
        Condition::Simple(keyword) => content.contains(keyword),
        Condition::Not(inner) => {
            let inner_result = evaluate_condition(content, inner);
            !inner_result
        }
        Condition::And(conditions) => {
            let result = conditions
                .iter()
                .all(|cond| evaluate_condition(content, cond));
            result
        }
        Condition::Or(conditions) => {
            let result = conditions
                .iter()
                .any(|cond| evaluate_condition(content, cond));
            result
        }
    };
    result
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_get_matched_simple() {
        let content = "hello world\nthis is a test\nkeyword here\nanother line\nrust programming";

        // 简单匹配测试
        let result = get_matched(content, "keyword");
        assert!(result.is_some());
        assert_eq!(
            result.unwrap(),
            "this is a test\nkeyword here\nanother line"
        );
    }

    #[test]
    fn test_get_matched_not() {
        let content = "hello world\nthis is a test\nkeyword here\nanother line\nrust programming";

        // 不匹配测试
        let result = get_matched(content, "notfound");
        assert!(result.is_none());
    }

    #[test]
    fn test_get_matched_and() {
        let content = "hello world\nthis is a test\nkeyword here\nanother line\nrust programming";
        // AND 条件测试
        let result = get_matched(content, "(hello AND world)");
        assert!(result.is_some());
        assert_eq!(result.unwrap(), "hello world");
    }

    #[test]
    fn test_get_matched_and_multi_lines() {
        let content = "hello world\nthis is a test\nkeyword here\nanother line\nrust programming";

        // AND 条件测试 - 修复后的逻辑
        let result = get_matched(content, "(hello AND another)");
        assert!(result.is_some());
        let result_str = result.unwrap();
        // 现在应该返回包含 "hello" 和 "another" 的所有行
        assert!(result_str.contains("hello world"));
        assert!(result_str.contains("another line"));

        // OR 条件测试
        let result = get_matched(content, "(hello OR programming)");
        assert!(result.is_some());
        let result_str = result.unwrap();
        assert!(result_str.contains("hello world") || result_str.contains("rust programming"));

        // NOT 条件测试
        let result = get_matched(content, "NOT notfound");
        assert!(result.is_some()); // 应该匹配，因为 notfound 不存在

        let result = get_matched(content, "NOT hello");
        assert!(result.is_none()); // 应该不匹配，因为 hello 存在
    }

    #[test]
    fn test_get_matched_and_multi_conditions() {
        let content = "hello world\nthis is a test\nkeyword here\nanother line\nrust programming";
        // 复杂条件测试
        let result = get_matched(content, "(hello AND world) OR (rust AND programming)");
        assert!(result.is_some());

        // 嵌套 NOT 测试
        let result = get_matched(content, "NOT (hello AND world)");
        assert!(result.is_none()); // 应该不匹配，因为 hello AND world 存在
    }

    #[test]
    fn test_parse_condition() {
        // 简单条件
        assert_eq!(
            parse_condition("hello").unwrap(),
            Condition::Simple("hello".to_string())
        );

        // NOT 条件
        assert_eq!(
            parse_condition("NOT hello").unwrap(),
            Condition::Not(Box::new(Condition::Simple("hello".to_string())))
        );

        // AND 条件
        assert_eq!(
            parse_condition("(hello AND world)").unwrap(),
            Condition::And(vec![
                Condition::Simple("hello".to_string()),
                Condition::Simple("world".to_string())
            ])
        );

        // OR 条件
        assert_eq!(
            parse_condition("(hello OR world)").unwrap(),
            Condition::Or(vec![
                Condition::Simple("hello".to_string()),
                Condition::Simple("world".to_string())
            ])
        );

        // 错误条件
        assert!(parse_condition("").is_err());
    }

    #[test]
    fn test_evaluate_condition() {
        let content = "hello world test";

        // 简单条件
        assert!(evaluate_condition(
            content,
            &Condition::Simple("hello".to_string())
        ));
        assert!(!evaluate_condition(
            content,
            &Condition::Simple("notfound".to_string())
        ));

        // AND 条件
        let and_condition = Condition::And(vec![
            Condition::Simple("hello".to_string()),
            Condition::Simple("world".to_string()),
        ]);
        assert!(evaluate_condition(content, &and_condition));

        // OR 条件
        let or_condition = Condition::Or(vec![
            Condition::Simple("hello".to_string()),
            Condition::Simple("notfound".to_string()),
        ]);
        assert!(evaluate_condition(content, &or_condition));

        // NOT 条件
        let not_condition = Condition::Not(Box::new(Condition::Simple("notfound".to_string())));
        assert!(evaluate_condition(content, &not_condition));
    }

    #[test]
    fn test_find_all_matching_lines_with_and_condition() {
        let content = "hello world\nthis is a test\nkeyword here\nanother line\nrust programming";

        // 测试 AND 条件跨行的情况
        let condition = Condition::And(vec![
            Condition::Simple("hello".to_string()),
            Condition::Simple("another".to_string()),
        ]);

        let result = find_all_matching_lines(content, &condition);
        // 应该返回包含 "hello" 和 "another" 的所有行
        assert_eq!(result.len(), 2);
        assert!(result.contains(&"hello world".to_string()));
        assert!(result.contains(&"another line".to_string()));
    }

    #[test]
    fn test_parse_complex_condition() {
        // 测试复杂括号表达式
        let result = parse_condition("(hello AND world) OR (rust AND programming)").unwrap();

        match result {
            Condition::Or(conditions) => {
                assert_eq!(conditions.len(), 2);
                // 第一个条件应该是 (hello AND world)
                if let Condition::And(first_and) = &conditions[0] {
                    assert_eq!(first_and.len(), 2);
                }
                // 第二个条件应该是 (rust AND programming)
                if let Condition::And(second_and) = &conditions[1] {
                    assert_eq!(second_and.len(), 2);
                }
            }
            _ => panic!("应该解析为 OR 条件"),
        }
    }
}
